#include <stdio.h>
#include <stdlib.h>
#include <sys/types.h> 
#include <sys/stat.h> 
#include <sys/io.h> 
#include <string.h>

#define puerto 0x378

struct driver_domotica{
	int relay1;
	int relay2;
	int relay3;
	int relay4;
};

void ayuda (void);

int main(int argc, char **argv)
{
	int nro_relay;
	int comando_int;

	char comando_str[5];
	char buff[2];

	strcpy(comando_str, "");

	struct stat datosDirectorio;
	struct driver_domotica driver;

	FILE *cfPtr;

	nro_relay = -1;
	comando_int = -1;

	if((lstat("/var/lib/domotica", &datosDirectorio)) == -1)
	{
		printf("\nCreando Directorio...\n");
		mkdir("/var/lib/domotica", 0755);
		printf("Listo!\n");
	}

	if((cfPtr = fopen("/var/lib/domotica/db.dat", "r")) == NULL)
	{
		printf("Inicializando archivo de datos...\n");

		driver.relay1 = 0;
		driver.relay2 = 0;
		driver.relay3 = 0;
		driver.relay4 = 0;

		cfPtr = fopen("/var/lib/domotica/db.dat", "w");
		fwrite(&driver, sizeof(struct driver_domotica), 1, cfPtr);
		fclose(cfPtr);
		printf("Listo!\n");
	}
	else
	{
		rewind(cfPtr);
		fread(&driver, sizeof(struct driver_domotica), 1, cfPtr);
		fclose(cfPtr);
	}

	if(argc < 2 || argc > 3)
	{
		ayuda();
		exit(0);
	}
	else
	{
		if(strcmp(argv[1], "-e") == 0)
		{
			nro_relay = atoi(argv[2]);

			switch(nro_relay)
			{
				case 1:
					printf("Encendiendo Relay1...\n");
					driver.relay1 = 1;
					printf("Listo!\n");
					break;

				case 2:
					printf("Encendiendo Relay2...\n");
					driver.relay2 = 1;
					printf("Listo!\n");
					break;
		
				case 3:
					printf("Encendiendo Relay3...\n");
					driver.relay3 = 1;
					printf("Listo!\n");
					break;
				
				case 4: 
					printf("Encendiendo Relay4...\n");
					driver.relay4 = 1;
					printf("Listo!\n");
					break;

				default:
					printf("\nERROR!!! Parametro numero de relay incorrecto!\n\n");
					break;
			}
		}
		else if(strcmp(argv[1], "-a") == 0)
		{
			nro_relay = atoi(argv[2]);

			switch(nro_relay)
			{
				case 1:
					printf("Apagando Relay1...\n");
					driver.relay1 = 0;
					printf("Listo!\n");
					break;

				case 2:
					printf("Apagando Relay2...\n");
					driver.relay2 = 0;
					printf("Listo!\n");
					break;
		
				case 3:
					printf("Apagando Relay3...\n");
					driver.relay3 = 0;
					printf("Listo!\n");
					break;
				
				case 4: 
					printf("Apagando Relay4...\n");
					driver.relay4 = 0;
					printf("Listo!\n");
					break;

				default:
					printf("\nERROR!!! Parametro numero de relay incorrecto!\n\n");
					break;
			}
		}
		else if(strcmp(argv[1], "-l") == 0)
		{
			printf("\nEstado de los Relays\n");
			printf("====== == === ======\n\n");
			if(driver.relay1 == 1)
				printf("	* Estado Relay1: ENCENDIDO\n");
			else
				printf("	* Estado Relay1: APAGADO\n");

			if(driver.relay2 == 1)
				printf("	* Estado Relay2: ENCENDIDO\n");
			else
				printf("	* Estado Relay2: APAGADO\n");

			if(driver.relay3 == 1)
				printf("	* Estado Relay3: ENCENDIDO\n");
			else
				printf("	* Estado Relay3: APAGADO\n");

			if(driver.relay4 == 1)
				printf("	* Estado Relay4: ENCENDIDO\n");
			else
				printf("	* Estado Relay4: APAGADO\n\n");
		} 
		else if(strcmp(argv[1], "-?") == 0 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)
			ayuda();	
		else if(strcmp(argv[1], "-X") == 0)
		{
			driver.relay1 = 0;
			driver.relay2 = 0;
			driver.relay3 = 0;
			driver.relay4 = 0;
		}
		else
		{
			printf("\nERROR!!! Comando incorrecto!\n\n");
			ayuda();
		}
	}

	if(nro_relay == 1 || nro_relay == 2 || nro_relay == 3 || nro_relay == 4 || strcmp(argv[1], "-X") == 0)
	{
		printf("Guardando cambios...\n");
		cfPtr = fopen("/var/lib/domotica/db.dat", "w");
		fwrite(&driver, sizeof(struct driver_domotica), 1, cfPtr);
		fclose(cfPtr);
		printf("Listo!\n");
	}

	sprintf(buff, "%d", driver.relay4); 
	strcat(comando_str, buff);
	sprintf(buff, "%d", driver.relay3); 
	strcat(comando_str, buff);
	sprintf(buff, "%d", driver.relay2); 
	strcat(comando_str, buff);
	sprintf(buff, "%d", driver.relay1); 
	strcat(comando_str, buff);


	if(strcmp(comando_str, "0000") == 0)
		comando_int = 0;
	else if(strcmp(comando_str, "0001") == 0)
		comando_int = 1;
	else if(strcmp(comando_str, "0011") == 0)
		comando_int = 3;
	else if(strcmp(comando_str, "0111") == 0)
		comando_int = 7;
	else if(strcmp(comando_str, "1111") == 0)
		comando_int = 15;
	else if(strcmp(comando_str, "0101") == 0)
		comando_int = 5;
	else if(strcmp(comando_str, "1001") == 0)
		comando_int = 9;
	else if(strcmp(comando_str, "1101") == 0)
		comando_int = 13;
	else if(strcmp(comando_str, "1011") == 0)
		comando_int = 11;
	else if(strcmp(comando_str, "0010") == 0)
		comando_int = 2;
	else if(strcmp(comando_str, "0110") == 0)
		comando_int = 6;
	else if(strcmp(comando_str, "1010") == 0)
		comando_int = 10;
	else if(strcmp(comando_str, "1110") == 0)
		comando_int = 14;
	else if(strcmp(comando_str, "0100") == 0)
		comando_int = 4;
	else if(strcmp(comando_str, "1100") == 0)
		comando_int = 12;
	else if(strcmp(comando_str, "1000") == 0)
		comando_int = 8;

	printf("\nCOMANDO_STR: %s  -  COMANDO_INT: %d\n\n", comando_str, comando_int);

	if(ioperm(puerto, 1, 1))
	{
		perror("ERROR AL ABRIR PUERTO PARALELO!");
		exit(1);
	}
	
	outb(comando_int, puerto);

	if(ioperm(puerto, 1, 0))
	{
		perror("ERROR AL CERRAR EL PUERTO PARALELO!");
		exit(1);
	}	

	return 0;
}

void ayuda(void)
{
	printf("\nModo de uso:\n");
	printf("==== == ===\n\n");
	printf("domotica (comando) (numero de relay)\n\n");
	printf("donde comando es -e para encender un relay, -a para apagar un relay y -l para listar\n");
	printf("el estado de los relays. Numero de relay es el contactor a cerrar, valido de 1 a 4.\n");
	printf("El comando -X apaga todos los relays de forma simultanea. No requiere parametros.\n");
	printf("El comando -l no necesita numero de relay.\n");
	printf("El comando -?, -h o --help muestra este mensaje.\n");
	printf("Ejemplo:\n\n");
	printf("./domotica -e 1 <- cierra el circuito del Relay1, permitiendo el paso de energia\n");
	printf("./domotica -a 1 <- abre el circuito del Relay1, impidiendo el paso de energia\n");
	printf("./domotica -l <- lista el estado de todos los relays\n\n");
}
